<?php
require('./../app/plugins/cos.php');
require ('./../app/plugins/cos-php-sdk-v5/cos-autoloader.php');
use Phalcon\Validation\Validator\PresenceOf;
use Phalcon\Validation\Validator\Regex as RegexValidator;
use Phalcon\Validation\Validator\Between;
use Phalcon\Validation\Validator\StringLength;
use Phalcon\Validation\Validator\Email;
use Qcloud_cos\Auth;
use Qcloud_cos\Cosapi;

/**
 * 云监控相关的控制基类
 *
 * 包含对于一些通用枚举类的redis缓存,去除掉冗余查询定位
 */
class CloudControllerBase extends ControllerBase
{


    //通用REDIS 键值存储的KEY
    const REDIS_KEY_CACHE_KEY_VALUE = "REDIS_KEY_KEY_VALUE_CACHE";
    //通用REDIS 兼职存储缓存超时时间
    const REDIS_CACHE_TIMEOUT_KEY_VALUE = 3;

    /******************************   通用业务逻辑快捷方法    ***********************************************************/

    /**
     * 验证类型
     * {
     *  key:
     *  type:
     *  message:
     *  min:
     *  max:
     *  messageMaximum
     *  messageMinimum
     * }
     *
     * 验证请求参数
     * @param $dict
     * @return bool
     */
    protected function checkRequestParams($dict, $isGet = false)
    {

        if ($dict) {
            $validation = new Phalcon\Validation();
            foreach ($dict as $item) {
                $key = $item['key'];
                $typeStr = $item['type'];
                $message = $item['message'];
                $types = explode("&", $typeStr);
                foreach ($types as $type) {
                    switch ($type) {
                        case "presence": {
                            $validation->add(
                                $key,
                                new PresenceOf(
                                    [
                                        'message' => $message,
                                    ]
                                )
                            );
                        };
                            break;
                        case "email": {
                            $validation->add(
                                $key,
                                new Email(
                                    [
                                        'message' => $message,
                                    ]
                                )
                            );
                        };
                            break;
                        case "phone":
                        case "number": {
                            $validation->add(
                                $key,
                                new RegexValidator(array('pattern' => '/^[0-9]+$/', 'message' => $message)
                                ));
                        };
                            break;
                        case "length": {
                            if (!$item['messageMaximum']) {
                                $item['messageMaximum'] = $item['message'];
                            }
                            if (!$item['messageMinimum']) {
                                $item['messageMinimum'] = $item['message'];
                            }
                            $validation->add($key,
                                new StringLength($item));
                        };
                            break;
                        case "regex": {
                            $pattern = $item['pattern'];
                            $validation->add(
                                $key,
                                new RegexValidator(array('pattern' => $pattern, 'message' => $message)
                                ));
                        };
                            break;
                    }
                }
            }
            if ($isGet) {
                $this->checkRequest($validation, $this->request->getQuery());
            } else {
                $this->checkRequest($validation, $this->request->getPost());
            }

        } else {
            $this->returnError("验证参数为空");
        }

    }

    /******************************     APP ID校验    ***********************************************************/
    protected function checkAppIdAndSecret(){
        $appId=$_SERVER["HTTP_APPID"];
        $appSec=$_SERVER["HTTP_APPSECRET"];
        if(empty($appId)||empty($appSec))
        {
            $this->returnError("Authorization Error");
        }
        $sql="SELECT count(*) FROM developer_project WHERE app_id=$appId and app_secret='$appSec'";
        $result=intval($this->fetchOne($sql,1000));
        if($result<1) {
            return $this->returnError("Authorization Error");
        }
        $sql="SELECT * FROM developer_project WHERE app_id=$appId";
        return $data = $this->fetchOne($sql);
    }


    /******************************     数据库操作,封装便捷方法    ***********************************************************/




    //通过uas_serial_id,判断是否为固定翼
    protected function isFixWingByUasId($uasId)
    {
        if ($uasId) {
            $name = $this->fetchOne("select m.name as modelName from plane p left join plane_model m on m.id=p.planeModel_id  where uas_serial_id='$uasId'");

            if($name){
                $uasPlane=$name["modelName"];
                if (strtoupper($uasPlane[0]) == "F"
                ) {
                    return true;
                }
            }else{
                return true;
            }




        }

        return false;
    }

    protected function generateInsertData($config)
    {
        $table = $config["table"];
        $fieldList = $config["fieldList"];
        $fieldUpdateItems = array();
        foreach ($fieldList as $key) {
            $value = $this->getPost($key);
            if (!empty($value)) {
                $fieldUpdateItems[$key] = $value;
            }
        }
        if ($this->insert($table, $fieldUpdateItems)) {
            $this->returnSuccess("更新成功");
        } else {
            $this->returnError("更新失败");
        }
    }

    /**
     * 删除快捷方法
     * @param $config
     */
    protected function generateDeleteData($config)
    {
        $table = $config["table"];
        $paramList = $config["paramList"];
        $whereStr = empty($config["where"]) ? "" : $config["where"];
        $whereAppend = null;

        if (!empty($paramList)) {
            $whereAppend = $this->generateExecuteWhereStr($paramList);
            if ($whereAppend && !empty($whereAppend[0])) {

                if (!empty($whereStr)) $whereStr .= " and ";
                $whereStr .= $whereAppend[0];
                $whereParamList = $whereAppend[1];

                if (!empty($whereStr)) {
                    $sqlStr = "delete from $table " . (empty($whereStr) ? "" : " where " . $whereStr);
                    $this->dbQuery->execute($sqlStr, $whereParamList);
                    if ($this->dbQuery->affectedRows() > 0) {
                        $this->saveDeleteLog($table, $whereParamList, $whereStr);
                        $this->returnSuccess("删除成功");
                    } else {
                        $this->returnError("删除失败");
                    }
                }


            }

        }

        $this->returnError("参数异常");
    }

    /**
     * 自动生成查询请求参数
     * @param $paramList
     * @return array|bool
     */
    protected function generateExecuteWhereStr($paramList)
    {
        $strWhereData = json_decode($this->getPost("filter_list"), true);

        $sqlStr = "";
        $paramValues = array();
        foreach ($paramList as $item) {
            $name = $item[0];
            $type = $item[1];
            $left = "";
            $right = "";
            if (count($item) >= 3) {
                $left = $item[2];
            }
            if (count($item) >= 4) {
                $right = $item[3];
            }

            $value = $strWhereData[$name];
            if (count($item) >= 5) {
                //真实名称sql名称
                $name = $item[4];
            }
            if (!empty($value)) {
                if (!empty($sqlStr)) {
                    $sqlStr .= " and ";
                }
                if ($type == "in") {
                    $sqlStr .= " $name $type $left?$right ";
                    array_push($paramValues, addslashes($value));
                } else {
                    $sqlStr .= " $name $type ? ";
                    array_push($paramValues, addslashes($left . "" . $value . "" . $right));
                }


            }
        }

        return [$sqlStr, $paramValues];

    }

    /**
     * 自动生成详情页
     * @param $config
     * @return array
     */
    protected function generateDetailData($config)
    {
        $table = $config["table"];
        $columnMapper = $config["column"];
        $strWhere = $config["where"];
        $columnString = "";
        foreach ($columnMapper as list($columnName, $columnTitle, $type)) {
            if (!empty($columnString)) {
                $columnString .= ",";
            }
            $columnString .= $columnName;
        }
        $sqlData = "select $columnString from $table as temp " . ($strWhere == null ? "" : " where " . $strWhere);
        $result = $this->fetchOne($sqlData);
        $titleKey = "";
        if (isset($config["titleKey"])) {
            $titleKey = $result[$config["titleKey"]];
        }
        $this->view->setVars(array("attrList" => json_encode($columnMapper),
            "pageData" => json_encode($result),
            "title" => $config["title"],
            "titleKey" => $titleKey,
            "pageKey" => $result[$config["keyName"]],
            "pageKeyName" => $config["keyName"]
        ));
    }

    /** 查询相关 */
    /**
     * 分页查询
     * @param $post
     * @param $column
     * @param $table
     * @param $strWhere
     * @param $orderStr
     */
    protected function postQueryByPage($columnMapper, $table, $paramList, $orderStr = null, $keyName = "")
    {
        $pageSize = intval($this->getPost("page_size"));
        $pageIndex = intval($this->getPost("page_index"));
        $orderName = $this->getPost("order_name");
        $orderType = $this->getPost("order_type");
        $pageStart = $pageSize * $pageIndex;

        $columnString = "";
        $nameList = array_keys($columnMapper);
        $titleList = array_values($columnMapper);

        foreach ($columnMapper as $key => $value) {
            if (!empty($columnString)) {
                $columnString .= ",";
            }
            $columnString .= $key;
        }
        $whereData = $this->generateQueryWhereStr($paramList);
        $strWhere = null;
        if (!empty($whereData[0])) {
            $strWhere = " where " . $whereData[0];
        }
        if (!empty($orderName) && !empty($columnMapper[$orderName])
            && !empty($orderType) && ($orderType == "desc" || $orderType == "asc")
        ) {
            $orderStr = $orderName . " " . $orderType;
        }
        if (!empty($orderStr)) {
            $array = explode(" ", $orderStr);
            if ($array[0] && !empty($columnMapper[$array[0]])) {
                $orderName = $array[0];
                $orderType = $array[1];
            }
        }

        $sqlCount = "select count(*) as total from $table as temp" . ($strWhere == null ? "" : $strWhere) . ($orderStr == null ? "" : " order by " . $orderStr);
        $sqlWhere = "select $columnString from $table as temp " . ($strWhere == null ? "" : $strWhere) . ($orderStr == null ? "" : " order by " . $orderStr) . " limit $pageStart,$pageSize";
        $countData = $this->dbQuery->fetchOne($sqlCount, \Phalcon\Db::FETCH_ASSOC, $whereData[1]);
        $sqlData = $this->dbQuery->fetchAll($sqlWhere, \Phalcon\Db::FETCH_ASSOC, $whereData[1]);

        $total = 0;
        if (!empty($sqlData)) {
            $total = $countData["total"];
            $keyList = array();
            for ($i = 0; $i < count($sqlData); $i++) {
                $sqlItem = $sqlData[$i];
                foreach ($sqlItem as $key => $value) {
                    //将key数据放入keyList中
                    //用于任何时候存取本行的关键数据
                    if (!empty($keyName) && $keyName == $key) {
                        array_push($keyList, $value);
                    }
                    $sqlData[$i][$key] = $this->filedItemChanged($table, $key, $value);
                }
            }

        }
        $resultArr = array(
            "orderName" => $orderName,
            "orderType" => $orderType,
            "pageIndex" => $pageIndex,
            "total" => $total,
            "nameList" => $nameList,
            "titleList" => $titleList,
            "keyList" => $keyList,
            "data" => $sqlData,
            "keyName"=>$keyName
        );
        $this->returnJson(json_encode($resultArr));
    }




    /**
     * 自动生成查询请求参数
     * @param $paramList
     * @return array|bool
     */
    protected function generateQueryWhereStr($paramList)
    {
        $strWhereData = json_decode($this->getPost("filter_list"), true);

        $sqlStr = "";
        $paramValues = array();
        foreach ($paramList as $item) {
            $name = $item[0];
            $type = $item[1];
            $left = "";
            $right = "";
            if (count($item) >= 3) {
                $left = $item[2];
            }
            if (count($item) >= 4) {
                $right = $item[3];
            }

            $value = $strWhereData[$name];
            $realName = $name;
            if (count($item) >= 5) {
                //真实名称sql名称
                $realName = $item[4];
            }
            if (isset($value)) {
                if (!empty($sqlStr)) {
                    $sqlStr .= " and ";
                }
                $sqlStr .= " $realName $type :$name ";

                $paramValues[$name] = addslashes($left . "" . $value . "" . $right);
            }
        }

        return [$sqlStr, $paramValues];

    }


    //更新并直接返回操作结果
    protected function generateUpdateData($config)
    {
        $this->updateSqlData($config);
        $this->returnSuccess("更新成功");
    }

    //更新数据库相关数据,并返回影响行数
    protected function updateSqlData($config)
    {
        $table = $config["table"];
        $fieldList = $config["fieldList"];
        $addItems = $config["addItems"];
        $preKey = $config["preKey"];
        $fieldUpdateItems = array();
        if ($addItems){
            $fieldUpdateItems = array_merge($fieldUpdateItems, $addItems);
        }
        foreach ($fieldList as $key) {
            if (($key=="html")or($key=="file_list")){
                $value = $_POST[$key];
            }else{
                $value = htmlspecialchars($this->getPost($key));
            }
            if ($value!=null&&count_chars($value)>0) {
                if (strpos($key, $preKey) === 0) {
                    $key = substr_replace($key, "", 0, strlen($preKey));
                }
                $fieldUpdateItems[$key] = $value;
            }

        }
        if (count($fieldUpdateItems) > 0) {
            $result = $this->update($table, $fieldUpdateItems, $config["where"]);
            return $result;
        }
        return true;

    }

    protected function insertSqlData($config)
    {
        $table = $config["table"];
        $fieldList = $config["fieldList"];
        $addItems = $config["addItems"];
        $preKey = $config["preKey"];
        $fieldUpdateItems = array();
        if ($addItems){
            $fieldUpdateItems = array_merge($fieldUpdateItems, $addItems);
        }
        foreach ($fieldList as $key) {
            if(($key=="html")or($key=="file_list")){
                $value = $_POST[$key];
            }else{
                $value = htmlspecialchars($this->getPost($key));
            }
            if (!empty($value)) {
                if (strpos($key, $preKey) == 0) {
                    $key = substr_replace($key, "", 0, strlen($preKey));
                }
                $fieldUpdateItems[$key] = $value;
            }

        }
        if (count($fieldUpdateItems) > 0) {
            $result = $this->insert($table, $fieldUpdateItems);
            return $result;
        }
        return true;
    }

    /******************************     上传头像到COS    ******************************************************/

    protected function uploadIconCos($base_img, $fileName)
    {

        $bucketName = $this->iconCos['bucket'];
        $path = "./../app/cache";
        $tempPath = $this->base64_image_content($base_img, $path);
        $dstPath = $this->iconCos['path'] . $fileName . ".png";
        Cosapi::del($bucketName, $dstPath);
        $uploadRet = Cosapi::upload($tempPath, $bucketName, $dstPath);
        if ($uploadRet['code'] == 0) {
            return $this->iconCos['url'] . $dstPath;
        } else {
            return $uploadRet['message'];
        }

    }

    /******************************    删除COS文件    ***********************************************************/
    protected function deleteFileCos($dstPath)
    {
        $cosClient = new Qcloud\Cos\Client(array(
            "region" => $this->filesCos["region"],
            "credentials" => array(
                "secretId" => $this->filesCos["secret_id"],
                "secretKey" => $this->filesCos["secret_key"]
            )
        ));
        try{
            $searchStr = $this->filesCos["url"];
            $key = str_replace($searchStr, "", $dstPath);
            $result = $cosClient->deleteObject(array(
                'Bucket' => $this->filesCos["bucket"] . "-" . $this->filesCos["appid"],
                'Key' => $key));
        } catch (\Exception $e) {
            $this->returnError($e);
        }

    }

//    protected function deleteFileCos($dstPath)
//    {
//        $bucketName = $this->filesCos["bucket"];
//        $delRet = Cosapi::del($bucketName, '0.3798337021505124 ');
//        var_dump($delRet);
//
//    }


    /******************************    通用临时数据    ***********************************************************/

    private function _getKeyValueSelectInfoByCache($config)
    {
        $isJsonString = $config["is_json"];
        $isCache = $config["is_cache"];
        $tableSql = $config["sql"];
        $keyTag = $config["key_tag"];
        $valueTag = $config["value_tag"];
        $resultArray = array();

        $redisKey = $this::REDIS_KEY_CACHE_KEY_VALUE . $tableSql;
        //是否使用缓存
        if ($isCache) {
            //已经有缓存,直接返回
            if ($this->redis->exists($redisKey)) {
                $jsonString = $this->redis->get($redisKey);
                if ($isJsonString) {
                    return $jsonString;
                } else {
                    return json_decode($jsonString, true);
                }
            }
        }
        $data = $this->fetchAll($tableSql);
        foreach ($data as $item) {
            $resultArray[$item[$keyTag]] = $item[$valueTag];
        }
        $jsonString = json_encode($resultArray);
        $this->redis->setex($redisKey, $this::REDIS_CACHE_TIMEOUT_KEY_VALUE, $jsonString);
        if ($isJsonString) {
            return $jsonString;
        } else {
            return $resultArray;
        }
    }

    //获取子系统类型信息
    protected function getSubSystemInfo($isJsonString = false, $isCache = false)
    {
        return $this->_getKeyValueSelectInfoByCache(array(
            "is_json" => $isJsonString,
            "is_cache" => $isCache,
            "sql" => "select id,system_name from subsystem_info",
            "key_tag" => "id",
            "value_tag" => "system_name"
        ));
    }

    //获取飞机类型的信息
    protected function getPlaneModelInfo($isJsonString = false, $isCache = false)
    {
        return $this->_getKeyValueSelectInfoByCache(array(
            "is_json" => $isJsonString,
            "is_cache" => $isCache,
            "sql" => "select id,name from plane_model order by id asc",
            "key_tag" => "id",
            "value_tag" => "name"
        ));
    }

    //获取飞机状态的信息
    protected function getPlaneTypeInfo($isJsonString = false, $isCache = false)
    {
        return $this->_getKeyValueSelectInfoByCache(array(
            "is_json" => $isJsonString,
            "is_cache" => $isCache,
            "sql" => "select id,name from plane_type order by id asc",
            "key_tag" => "id",
            "value_tag" => "name"
        ));
    }

    //获取相机类型的信息
    protected function getCameraTypeInfo($isJsonString = false, $isCache = false)
    {
        return $this->_getKeyValueSelectInfoByCache(array(
            "is_json" => $isJsonString,
            "is_cache" => $isCache,
            "sql" => "select id,name from camera_model order by id asc",
            "key_tag" => "id",
            "value_tag" => "name"
        ));
    }

    //获取相机类型的信息
    protected function getCameraType($isJsonString = false, $isCache = false)
    {
        return $this->_getKeyValueSelectInfoByCache(array(
            "is_json" => $isJsonString,
            "is_cache" => $isCache,
            "sql" => "SELECT CASE camera_type WHEN '' THEN 'NONE'ELSE camera_type END AS camera_type FROM flight_mission GROUP BY camera_type",
            "key_tag" => "camera_type",
            "value_tag" => "camera_type"
        ));
    }

    //获取固件类型的信息
    protected function getFirmwareTypeInfo($isJsonString = false, $isCache = false)
    {
        return $this->_getKeyValueSelectInfoByCache(array(
            "is_json" => $isJsonString,
            "is_cache" => $isCache,
            "sql" => "select id,name from firmware_type order by id asc",
            "key_tag" => "id",
            "value_tag" => "name"
        ));
    }
    
    //获取相机类型的信息
    protected function getLaserScannerTypeInfo($isJsonString = false, $isCache = false)
    {
        return $this->_getKeyValueSelectInfoByCache(array(
                "is_json" => $isJsonString,
                "is_cache" => $isCache,
                "sql" => "select id,name from laser_scanner_type order by id asc",
                "key_tag" => "id",
                "value_tag" => "name"
        ));
    }
    
    //获取相机类型的信息
    protected function getIMUTypeInfo($isJsonString = false, $isCache = false)
    {
        return $this->_getKeyValueSelectInfoByCache(array(
                "is_json" => $isJsonString,
                "is_cache" => $isCache,
                "sql" => "select id,name from imu_type order by id asc",
                "key_tag" => "id",
                "value_tag" => "name"
        ));
    }

    //获取角色信息
    protected function getRoleInfo($isJsonString = false, $isCache = false)
    {
        $roleArray = array(
            MonitorLoginUser::USER_ROLE_SYSTEM_ADMIN => "超级管理员",
            MonitorLoginUser::USER_ROLE_SUBSYSTEM_ADMIN => "系统管理员",
            MonitorLoginUser::USER_ROLE_NORMAL => "普通用户",
        );
        if ($isJsonString) {
            return json_encode($roleArray);
        } else {
            return $roleArray;
        }
    }

    //获取飞机区域状态的信息
    protected function getPlaneAreaInfo($isJsonString = false, $isCache = false)
    {
        return $this->_getKeyValueSelectInfoByCache(array(
            "is_json" => $isJsonString,
            "is_cache" => $isCache,
            "sql" => "select id,name from plane_area order by id asc",
            "key_tag" => "id",
            "value_tag" => "name"
        ));
    }

    //获取省份信息
    public function getProvinceInfo($isJsonString = false, $isCache = false)
    {

        return $this->_getKeyValueSelectInfoByCache(array(
            "is_json" => $isJsonString,
            "is_cache" => $isCache,
            "sql" => "select id,name from city where parent_id=1",
            "key_tag" => "id",
            "value_tag" => "name"
        ));
    }

    //通用的处理字段的方法
    public function filedItemChanged($table, $name, $value)
    {
        switch ($name) {
            case "phone": {
                if (empty($value)) {
                    $value = "";
                }
            };
                break;
        }
        return $value;
    }


    function sendEmail($address, $content, $subject)
    {
        $mail = new PHPMailer();
        $mail->isSMTP();                                      // Set mailer to use SMTP
        $mail->Host = 'smtp.exmail.qq.com';  // Specify main and backup SMTP servers
        $mail->SMTPAuth = true;                               // Enable SMTP authentication
        $mail->Username = 'cloud_service@feimarobotics.com';                 // SMTP username
        $mail->Password = 'Feima@CloudService2017';                           // SMTP password
        $mail->SMTPSecure = 'ssl';                            // Enable TLS encryption, `ssl` also accepted
        $mail->Port = 465;                                    // TCP port to connect to
        $mail->setFrom('cloud_service@feimarobotics.com', 'FeimaRobotics');
        $mail->addAddress($address);     // Add a recipient
        $mail->isHTML(true);
        $mail->Subject = $subject;
        $mail->Body = $content;
        $mail->CharSet = "UTF-8";
        if (!$mail->send()) {
            return 'error: ' . $mail->ErrorInfo;
        } else {
            return 'success';
        }
    }

    /******************************   跳转到错误页面    ***********************************************************/

    /**
     * 转向错误页面
     * @param $errorTitle
     * @param $errorMsg
     */
    public function transferErrorPage($errorTitle, $errorMsg)
    {
        $htmlString = "<!doctype html>
<html>
<head>
<meta charset=\"UTF-8\">
<title>Error!</title>

<style>
	body {background-color: #f2f2f2; margin: 0; font-family: PingFangSC-Regular, sans-serif;}	
	table {height: 600px; width: 100%;}
	table tr td {width: 50%;}
	p {margin: 0; padding: 0; color: #3a88f4;}
</style>
</head>

<body>
<table>
	<tr>
		<td>
			<div style=\"float: right; width: 400px; margin-right: 60px;\">
				<p style=\"font-size: 3.0em; font-weight: bolder;\">$errorTitle</p>
				<p style=\"font-size: 1.0em;color: darkgrey;\">$errorMsg</p>
			</div>
		</td>
		<td>
			<img src=\"/images/web_error.png\" style=\"float: left;\">
		</td>
	</tr>
</table>


</body>
</html>";
        echo $htmlString;
        exit(0);
    }

}